/**
  ******************************************************************************
  * @file      timer.h
  * @author    Dragon.Chen
  * @version   V1.0.2
  * @date      12-10-2014
  * @brief     定时器容器(时间粒度为秒，也意味最大误差为1秒，如果需要高精度，使用gettimeofday)
  * @attention 由于定时器用于心跳包，回调函数都是一样，出于对内存和效率考虑，直接将回调函数放在
  *            Timer_Manage_T的结构体，统一管理。如果有特殊需求，请分别对每个定时器设置回调函数。
  ******************************************************************************
  *
  * <h2><center>&copy; COPYRIGHT 2014 上海今中网络科技有限公司 </center></h2>
  ******************************************************************************
  */

#ifndef __TIMER__H__
#define __TIMER__H__

#include "includes.h"

typedef struct _timer_manage_t
{
    int             timerMax;
    int             timerSize;
    TIMER_T       **timerArray;
    TIMER_EVENT_T  *callback;
} TIMER_MANAGE_T;
extern TIMER_MANAGE_T  timerManage;

/**
  * @brief  向下过滤
  *         向下过滤原理:
  *              21                    []               24                 24
  *             /  \                  /  \             /  \               /  \
  *           24    31   删除21=>    24    31   =>    []    31   =>      26   31
  *          /  \   /              /  \             /  \               /  \
  *         65  26 32             65  26 32        65  26 32          65  32
  * @param  arg1:hole
  * @retval NULL
  */
static inline void
percolate_down(int hole)
{
    int      child;
    TIMER_T *timer = timerManage.timerArray[hole];

    for (/*null*/; ((hole*2+1)<=(timerManage.timerSize-1)); hole=child)
    {
        child = hole*2+1;
        if ( (child < (timerManage.timerSize-1)) &&
             (timerManage.timerArray[child]->expire > timerManage.timerArray[child+1]->expire) )
            child++;

        if (timer->expire > timerManage.timerArray[child]->expire)
        {
            timerManage.timerArray[hole] = timerManage.timerArray[child];
            timerManage.timerArray[hole]->index = hole;
        }
        else
        {
            break;
        }
    }

    timerManage.timerArray[hole] = timer;
    timerManage.timerArray[hole]->index = hole;
}

/**
  * @brief  向上过滤
  * @param  arg1:hole
  * @retval NULL
  */
static inline void
percolate_up(int hole)
{
    int      parent;
    TIMER_T *timer = timerManage.timerArray[hole];

    for (/*null*/; hole>0; hole=parent)
    {
        parent = (hole-1)/2;
        if (timer->expire >= timerManage.timerArray[parent]->expire)
            break;

        timerManage.timerArray[hole] = timerManage.timerArray[parent];
        timerManage.timerArray[hole]->index = hole;
    }

    timerManage.timerArray[hole] = timer;
    timerManage.timerArray[hole]->index = hole;
}

/**
  * @brief  初始化定时器
  * @param  arg1:最大容量
  * @retval NULL
  */
void init_timer(int max, TIMER_EVENT_T *cb);

/**
  * @brief  添加定时器
  * @param  arg1:定时器
  * @retval 成功返回0，否则-1
  */
int add_timer(TIMER_T *timer);

/**
  * @brief  调整定时器
  * @param  arg1:定时器
  * @retval NULL
  */
static inline void
adjust_timer(TIMER_T *timer, int expire)
{
    if (timer->expire <= expire)
    {
        timer->expire = expire;
        percolate_down(timer->index);
    }
    else
    {
        timer->expire = expire;
        percolate_up(timer->index);
    }
}

/**
  * @brief  获取最小定时器数值
  * @param  NULL
  * @retval NULL
  */
#define get_min_timer_value() \
              ( (timerManage.timerArray[0] == NULL) ?  \
                (time(NULL)+WORKER_EPOLL_WAIT_TIME/1000) : timerManage.timerArray[0]->expire )

/**
  * @brief  获取定时器容器当前被使用的大小
  * @param  NULL
  * @retval NULL
  */
#define get_timer_size() \
            timerManage.timerSize

/**
  * @brief  删除定时器
  * @param  arg1:定时器
  * @retval NULL
  */
void delete_timer(TIMER_T *timer);

/**
  * @brief  定时器检测事件
  * @param  arg1:void
  * @retval NULL
  */
void timer_tick();

/**
  * @brief  释放所有的定时器
  * @param  arg1:void
  * @retval NULL
  */
void finalize_timer();

#endif

/******************* (C) COPYRIGHT 2014 上海今中网络科技有限公司 *****END OF FILE****/





